package main

import (
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/PuerkitoBio/goquery"
	"github.com/hu17889/go_spider/core/common/page"
)

type benchmarksInfo struct {
	ProcessorName   string
	RefererUrl      string
	Description     string
	SingleCoreScore string
	MultiCoresScore string
}

var infos map[string]*benchmarksInfo

func init() {
	infos = make(map[string]*benchmarksInfo)
}

func processCommaString(str string) string {
	if strings.Contains(str, ",") {
		return "\"" + str + "\""
	}

	return str
}

type GeekBenchProcessor struct{}

func NewGeekBenchProcessor() *GeekBenchProcessor {
	return &GeekBenchProcessor{}
}

func (t *GeekBenchProcessor) Process(p *page.Page) {
	if !p.IsSucc() {
		log.Printf("Err: %s", p.Errormsg())
		return
	}

	q := p.GetHtmlParser()

	// 单核
	q.Find("#single-core table tr").Each(func(i int, s *goquery.Selection) {
		if s.HasClass("stacked-heading") {
			return
		}

		processorName := processCommaString(strings.TrimSpace(s.Find("td.name a").Text()))
		refererUrl := processCommaString(fmt.Sprintf("https://browser.geekbench.com%s", strings.TrimSpace(s.Find("td.name a").AttrOr("href", ""))))
		description := processCommaString(strings.TrimSpace(s.Find("td.name .description").Text()))
		score := processCommaString(strings.TrimSpace(s.Find("td.score").Text()))
		fmt.Printf("ProcessorName: %s\nRefererUrl: %s\nDescription: %s\nSingle Core Score: %s\n\n",
			processorName, refererUrl, description, score)

		if info, ok := infos[processorName]; ok {
			info.SingleCoreScore = score
		} else {
			infos[processorName] = &benchmarksInfo{
				ProcessorName:   processorName,
				RefererUrl:      refererUrl,
				Description:     description,
				SingleCoreScore: score,
			}
		}
	})

	// 多核
	q.Find("#multi-core table tr").Each(func(i int, s *goquery.Selection) {
		if s.HasClass("stacked-heading") {
			return
		}

		processorName := processCommaString(strings.TrimSpace(s.Find("td.name a").Text()))
		refererUrl := processCommaString(fmt.Sprintf("https://browser.geekbench.com%s", strings.TrimSpace(s.Find("td.name a").AttrOr("href", ""))))
		description := processCommaString(strings.TrimSpace(s.Find("td.name .description").Text()))
		score := processCommaString(strings.TrimSpace(s.Find("td.score").Text()))
		fmt.Printf("ProcessorName: %s\nRefererUrl: %s\nDescription: %s\nMulti Cores Score: %s\n\n",
			processorName, refererUrl, description, score)

		if info, ok := infos[processorName]; ok {
			info.MultiCoresScore = score
		} else {
			infos[processorName] = &benchmarksInfo{
				ProcessorName:   processorName,
				RefererUrl:      refererUrl,
				Description:     description,
				MultiCoresScore: score,
			}
		}
	})
}

func (t *GeekBenchProcessor) Finish() {
	log.Printf("处理完毕！")

	f, err := os.OpenFile("./geekbench.csv", os.O_RDWR|os.O_CREATE, 0644)
	assertErr(err)

	f.Write([]byte{0xef, 0xbb, 0xbf}) //UTF-8 BOM

	columns := []string{"参考网址", "单核得分", "多核得分", "处理器编号", "描述"}
	f.WriteString(strings.Join(columns, ",") + "\n")

	var rows []string
	for _, info := range infos {
		var row []string
		row = append(row,
			info.RefererUrl,
			info.SingleCoreScore,
			info.MultiCoresScore,
			info.ProcessorName,
			info.Description,
		)
		rows = append(rows, strings.Join(row, ","))
	}

	f.WriteString(strings.Join(rows, "\n"))
	f.Close()
}
